import threading
import time
import random
from datetime import datetime, timezone, timedelta
from performance.runner.network_monitor.network_monitor_entrance import exec_network_monitor
from performance.runner.resource_monitor.resource_monitor_entrance import exec_resource_monitor
from performance.runner.constants import (
    CWD_PATH, 
    FEATURES, 
    NETWORK_MONITOR_TYPE, 
    RESOURCE_MONITOR_TYPE, 
    PERFORMANCE_LOG_DIR, 
    RESOURCE_MONITOR_DELAY_PERIOD
)
from performance.runner.logger import create_general_logger


class PerformanceTestRunner:
    """
    性能测试运行器类，负责管理和执行所有特性的性能测试。
    """
    
    def __init__(self):
        """
        初始化性能测试运行器。
        """
        self.start_time_timestamp = datetime.now(timezone.utc).astimezone().strftime("%Y%m%d_%H%M%S")
        log_file = f'{PERFORMANCE_LOG_DIR}_{self.start_time_timestamp}'
        self.performance_log_path = CWD_PATH / PERFORMANCE_LOG_DIR / log_file
        self.general_logger = create_general_logger(self.performance_log_path)

        # 添加分界线日志
        self.general_logger.info('=' * 80)
        self.general_logger.info(f'Performance Test new round start at {self.start_time_timestamp}!')
        self.general_logger.info('=' * 80)
    
    def install_feature(self, feature_category: str):
        """
        安装指定特性。
        
        :param feature_category: 特性类别字符串，如 'default'、'colocation' 等。
        """
        self.general_logger.info(f'installing feature [{feature_category}]')
        # 这里写特性安装逻辑
        return

    def uninstall_feature(self, feature_category: str):
        """
        卸载指定特性。
        
        :param feature_category: 特性类别字符串，如 'default'、'colocation' 等。
        """
        self.general_logger.info(f'uninstalling feature [{feature_category}]')
        # 这里写特性卸载逻辑
        return

    def run_feature_test(self, feature_category: str):
        """
        执行单个特性的性能测试，包括安装、network/resource监控线程启动、卸载。
        
        :param feature_category: 特性类别字符串。
        """
        self.install_feature(feature_category)
        threads = []

        def network_monitor_wrapper():
            """
            network_monitor 线程包装函数，负责异常捕获和日志记录。
            """
            self.general_logger.info(f"[{feature_category}] network_monitor 启动。")
            try: 
                exec_network_monitor(feature_category, self.performance_log_path / NETWORK_MONITOR_TYPE, csv=True)
                self.general_logger.info(f"[{feature_category}] network_monitor 完成, 请查看采集信息。")
            except Exception:
                self.general_logger.error(f"[{feature_category}] network_monitor 异常, 请查看的步骤日志。")

        def resource_monitor_wrapper():        
            """
            resource_monitor 线程包装函数，负责异常捕获和日志记录。
            """
            self.general_logger.info(f"[{feature_category}] resource_monitor 启动。")
            try:
                exec_resource_monitor(feature_category, self.performance_log_path / RESOURCE_MONITOR_TYPE, csv=True)
                self.general_logger.info(f"[{feature_category}] resource_monitor 完成, 请查看采集信息。")
            except Exception:
                self.general_logger.error(f"[{feature_category}] resource_monitor 异常, 请查看的步骤日志。")

        t1 = threading.Thread(target=network_monitor_wrapper)
        t2 = threading.Thread(target=resource_monitor_wrapper)
        threads.extend([t1, t2])
        t1.start()
        t2.start()
        for t in threads:
            t.join()
        self.uninstall_feature(feature_category)
        self.general_logger.info(f"[{feature_category}] 性能测试结束")
        
    def schedule_and_run_all_features(self):
        """
        为每个特性生成当前时间后 DELAY 小时内的随机启动时间，
        并在该时间点以线程方式启动特性测试。
        所有特性测试完成后，主程序自动结束。
        """
        # 加载配置的环境变量
        from dotenv import load_dotenv
        load_dotenv()
        now = datetime.now(timezone.utc).astimezone()
        threads = []
        for feature in FEATURES:
            delta_seconds = random.randint(0, int(RESOURCE_MONITOR_DELAY_PERIOD * 60 * 60))
            start_time = now + timedelta(seconds=delta_seconds)
            self.general_logger.info(f"[{feature}]将在  {start_time.strftime('%H:%M:%S')} 启动测试")

            def delayed_run(feature=feature, start_time=start_time):
                wait = (start_time - datetime.now(timezone.utc).astimezone()).total_seconds()
                if wait > 0:
                    time.sleep(wait)
                self.run_feature_test(feature)

            t = threading.Thread(target=delayed_run)
            t.start()
            threads.append(t)
        for t in threads:
            t.join()
        self.general_logger.info("所有特性测试已完成")
